﻿function Get-DNSServerSearchOrder {
<#
.SYNOPSIS
Modifies DNSServerSearchOrder using Windows Management Instrumentation (WMI)
.DESCRIPTION
Modifies DNSServerSearchOrder using Windows Management Instrumentation (WMI) on Network Interface Cards configured with a static IP address.
.PARAMETER ComputerName
The computer to perform action against. Defaults to the local computer if not specified. Accepts ValueFromPipeline and ValueFromPipelineByPropertyName.
.PARAMETER NetConnectionId
Only NICs matching the specified NetConnectionId will be modified
.PARAMETER DefaultGatewayPresentOnly
Switch-parameter to modify NIC with a default gateway present only
.PARAMETER Logfile
Path to log-file (only errors is logged)
.EXAMPLE
Import-Module ActiveDirectory;Get-ADComputer -filter * | Select-Object @{l='computername';e={$_.Name}} | Get-DNSServerSearchOrder
.EXAMPLE
Get-DNSServerSearchOrder -DefaultGatewayPresentOnly -Logfile c:\errors.txt
.EXAMPLE
Get-DNSServerSearchOrder -NetConnectionId "Local Area Connection"
.NOTES
AUTHOR:    Jan Egil Ring
BLOG:      http://blog.powershell.no
LASTEDIT:  24.10.2011
#Requires -Version 2.0
#>

    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]
        [string[]]$ComputerName = "localhost",
        [string]$NetConnectionId,
        [switch]$DefaultGatewayPresentOnly,
        [string]$Logfile
    )
    BEGIN {
    
       if ($logfile) {
        New-Item -Path $Logfile -ItemType file -Force | Out-Null
        }         

    }
    PROCESS {
        if ($PSBoundParameters.ContainsKey('computername')) {
            foreach ($computer in $computername) {
                Write-Verbose 'Input from parameter'
                Get-DNSServerSearchOrderWorker -computername $computername
            }
        } else {
            Write-Verbose 'Input from pipeline'
            Get-DNSServerSearchOrderWorker -computername $computername
        }
    }
}

#Helper function
function Get-DNSServerSearchOrderWorker {
    param($computername)
    $continue = $True
    try {
        if ((Test-Connection -ComputerName $computername -Count 1 -Quiet) -and ($computersystem = Get-WmiObject -Class win32_computersystem -Computername $computername -ErrorAction stop)) {
        Write-Verbose "Connected to computer $computername"

        $connectivity = "Success"


        $DHCPEnabledNICs = Get-WmiObject -Query "SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = TRUE AND DHCPEnabled = TRUE" -ComputerName $computername -ErrorAction Stop
        $NICs = Get-WmiObject -Query "SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = TRUE AND DHCPEnabled = FALSE" -ComputerName $computername -ErrorAction Stop
        $nicinfo = @{}

        if ($DefaultGatewayPresentOnly) {
        Write-Verbose 'Filtering NICs with default gateway present'
        $NICs = $NICs | Where-Object {$_.DefaultIPGateway}
        }
        
        if ($NetConnectionId) {
        Write-Verbose "Searching for NIC with NetConnectionId $NetConnectionId"
        $NetConnectionIdMatch = Get-WmiObject -Query "SELECT * FROM Win32_NetworkAdapter WHERE NetConnectionId = `'$NetConnectionId`'" -ComputerName $computername
        $NICs = $NICs | Where-Object {$_.Index -eq $NetConnectionIdMatch.index}
        if ($NICs) {
        Write-Verbose "Found NIC with NetConnectionId $NetConnectionId"
                   }
        }
        
        if ($NICs) {
        
        $DHCPNetConnectionId = @()
        $NetConnectionId = @()
        $DNSServerSearchOrder = @()
        $Description = @()
        

        foreach ($NIC in $NICs) {
        
        Write-Verbose "Processing NIC $($NIC.Description)"

        $NetConnectionId  += (Get-WmiObject -Query "SELECT * FROM Win32_NetworkAdapter WHERE Index = $($NIC.Index)" -ComputerName $computername -ErrorAction Stop).NetConnectionId
        $Description += $NIC.Description

        Write-Verbose "Retrieving DNSServerSearchOrder"

       
        $DNSServerSearchOrder += $NIC.DNSServerSearchOrder

    }
        $nicinfo.NetConnectionId = $NetConnectionId
        $nicinfo.DNSServerSearchOrder = $DNSServerSearchOrder
        $nicinfo.Description = $Description
        
        $nicinfo.StaticIPEnabledNICs = ($NICs | Measure-Object).count

        }
        else {
        $nicinfo.StaticIPEnabledNICs = ($NICs | Measure-Object).count
        }

        if ($DHCPEnabledNICs) {
        
       

        foreach ($DHCPNIC in $DHCPEnabledNICs) {
        
        Write-Verbose "Processing DHCP-NIC $($DHCPNIC.Description)"

        $DHCPNetConnectionId  += (Get-WmiObject -Query "SELECT * FROM Win32_NetworkAdapter WHERE Index = $($DHCPNIC.Index)" -ComputerName $computername -ErrorAction Stop).NetConnectionId

        $nicinfo.DHCPNetConnectionId = $DHCPNetConnectionId
        $nicinfo.DHCPEnabledNICs = ($DHCPEnabledNICs | Measure-Object).count

        }
        }
    else {
        $nicinfo.DHCPEnabledNICs = ($DHCPEnabledNICs | Measure-Object).count
        }
        
        }

    else {
        $connectivity = "Failed (ping)"
    }

        
    } 
    
    catch {
        Write-Verbose "An error occured connecting to computer $computername"
        Write-Verbose $error[0].exception

        $connectivity = "Failed (RPC)"

        
        if ($logfile) {
        $computername | Out-File -FilePath $Logfile -Append
        $error[0].exception | Out-File -FilePath $Logfile -Append
        }
    }
        
        Write-Verbose "Writing output object"
                
        $computerinfo = @{}
        if ($computersystem.name) {
        $computerinfo.ComputerName = $computersystem.name
        }
        else {
        $computerinfo.ComputerName = $($computername)
        }
        $computerinfo.NICCount = ($nicinfo.StaticIPEnabledNICs + $nicinfo.DHCPEnabledNICs)
        $computerinfo.StaticIPEnabledNICs = $nicinfo.StaticIPEnabledNICs
        $computerinfo.DHCPEnabledNICs = $nicinfo.DHCPEnabledNICs
        if ($nicinfo.NetConnectionID) {
        $computerinfo.StaticIPNICNetConnectionID = ($nicinfo | Select-Object @{Name='NetConnectionID';Expression={[string]::join(",", ($_.NetConnectionID))}}).NetConnectionID
        }
        if ($nicinfo.DHCPNetConnectionID) {
        $computerinfo.DHCPNICNetConnectionID = ($nicinfo | Select-Object @{Name='DHCPNetConnectionID';Expression={[string]::join(",", ($_.DHCPNetConnectionID))}}).DHCPNetConnectionID
        }
        if ($nicinfo.Description) {
        $computerinfo.StaticIPNICDescription = ($nicinfo | Select-Object @{Name='Description';Expression={[string]::join(",", ($_.Description))}}).Description
        }
        if ($nicinfo.DNSServerSearchOrder) {
        $computerinfo.StaticIPNICDNSServerSearchOrder = ($nicinfo | Select-Object @{Name='DNSServerSearchOrder';Expression={[string]::join(",", ($_.DNSServerSearchOrder))}}).DNSServerSearchOrder
        }
        $computerinfo.Connectivity = $connectivity
                        
        $obj = New-Object -TypeName PSObject -Property $computerinfo

        Write-Output $obj | Select-Object ComputerName,Connectivity,NICCount,StaticIPEnabledNICs,DHCPEnabledNICs,StaticIPNICNetConnectionID,StaticIPNICDescription,StaticIPNICDNSServerSearchOrder,DHCPNICNetConnectionID
}